package com.imut.lagain.repository;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.imut.lagain.entity.DataOperationLog;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 数据操作日志数据访问层
 */
@Mapper
public interface DataOperationLogRepository extends BaseMapper<DataOperationLog> {
    
    /**
     * 根据用户ID查询操作日志
     * @param userId 用户ID
     * @param page 分页参数
     * @return 操作日志分页列表
     */
    @Select("SELECT * FROM data_operation_log WHERE user_id = #{userId} ORDER BY operation_time DESC")
    IPage<DataOperationLog> findByUserId(@Param("userId") Long userId, Page<DataOperationLog> page);
    
    /**
     * 根据用户ID分页查询操作日志
     * @param userId 用户ID
     * @param page 分页参数
     * @return 操作日志分页列表
     */
    @Select("SELECT * FROM data_operation_log WHERE user_id = #{userId} ORDER BY operation_time DESC")
    IPage<DataOperationLog> findByUserIdWithPage(@Param("userId") Long userId, Page<DataOperationLog> page);
    
    /**
     * 根据操作类型查询日志
     * @param operationType 操作类型
     * @param page 分页参数
     * @return 操作日志分页列表
     */
    @Select("SELECT * FROM data_operation_log WHERE operation_type = #{operationType} ORDER BY operation_time DESC")
    IPage<DataOperationLog> findByOperationType(@Param("operationType") String operationType, Page<DataOperationLog> page);
    
    /**
     * 根据操作类型分页查询日志
     * @param operationType 操作类型
     * @param page 分页参数
     * @return 操作日志分页列表
     */
    @Select("SELECT * FROM data_operation_log WHERE operation_type = #{operationType} ORDER BY operation_time DESC")
    IPage<DataOperationLog> findByOperationTypeWithPage(@Param("operationType") String operationType, Page<DataOperationLog> page);
    
    /**
     * 根据表名查询日志
     * @param tableName 表名
     * @param page 分页参数
     * @return 操作日志分页列表
     */
    @Select("SELECT * FROM data_operation_log WHERE table_name = #{tableName} ORDER BY operation_time DESC")
    IPage<DataOperationLog> findByTableName(@Param("tableName") String tableName, Page<DataOperationLog> page);
    
    /**
     * 根据表名分页查询日志
     * @param tableName 表名
     * @param page 分页参数
     * @return 操作日志分页列表
     */
    @Select("SELECT * FROM data_operation_log WHERE table_name = #{tableName} ORDER BY operation_time DESC")
    IPage<DataOperationLog> findByTableNameWithPage(@Param("tableName") String tableName, Page<DataOperationLog> page);
    
    /**
     * 根据记录ID查询日志
     * @param recordId 记录ID
     * @return 操作日志列表
     */
    @Select("SELECT * FROM data_operation_log WHERE record_id = #{recordId} ORDER BY operation_time DESC")
    List<DataOperationLog> findByRecordId(@Param("recordId") Long recordId);
    
    /**
     * 根据记录ID分页查询日志
     * @param recordId 记录ID
     * @param page 分页参数
     * @return 操作日志分页列表
     */
    @Select("SELECT * FROM data_operation_log WHERE record_id = #{recordId} ORDER BY operation_time DESC")
    IPage<DataOperationLog> findByRecordIdWithPage(@Param("recordId") Long recordId, Page<DataOperationLog> page);
    
    /**
     * 根据表名和记录ID查询日志
     * @param tableName 表名
     * @param recordId 记录ID
     * @return 操作日志列表
     */
    @Select("SELECT * FROM data_operation_log WHERE table_name = #{tableName} AND record_id = #{recordId} ORDER BY operation_time DESC")
    List<DataOperationLog> findByTableNameAndRecordId(@Param("tableName") String tableName, @Param("recordId") Long recordId);
    
    /**
     * 根据用户ID和操作类型查询日志
     * @param userId 用户ID
     * @param operationType 操作类型
     * @param page 分页参数
     * @return 操作日志分页列表
     */
    @Select("SELECT * FROM data_operation_log WHERE user_id = #{userId} AND operation_type = #{operationType} ORDER BY operation_time DESC")
    IPage<DataOperationLog> findByUserIdAndOperationType(@Param("userId") Long userId, @Param("operationType") String operationType, Page<DataOperationLog> page);
    
    /**
     * 根据IP地址查询日志
     * @param ipAddress IP地址
     * @param page 分页参数
     * @return 操作日志分页列表
     */
    @Select("SELECT * FROM data_operation_log WHERE ip_address = #{ipAddress} ORDER BY operation_time DESC")
    IPage<DataOperationLog> findByIpAddress(@Param("ipAddress") String ipAddress, Page<DataOperationLog> page);
    
    /**
     * 根据IP地址分页查询日志
     * @param ipAddress IP地址
     * @param page 分页参数
     * @return 操作日志分页列表
     */
    @Select("SELECT * FROM data_operation_log WHERE ip_address = #{ipAddress} ORDER BY operation_time DESC")
    IPage<DataOperationLog> findByIpAddressWithPage(@Param("ipAddress") String ipAddress, Page<DataOperationLog> page);
    
    /**
     * 查询指定时间范围内的操作日志
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @param page 分页参数
     * @return 操作日志分页列表
     */
    @Select("SELECT * FROM data_operation_log WHERE operation_time BETWEEN #{startTime} AND #{endTime} ORDER BY operation_time DESC")
    IPage<DataOperationLog> findByOperationTimeBetween(@Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime, Page<DataOperationLog> page);
    
    /**
     * 查询用户在指定时间范围内的操作日志
     * @param userId 用户ID
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 操作日志列表
     */
    @Select("SELECT * FROM data_operation_log WHERE user_id = #{userId} AND operation_time BETWEEN #{startTime} AND #{endTime} ORDER BY operation_time DESC")
    List<DataOperationLog> findByUserIdAndOperationTimeBetween(@Param("userId") Long userId, @Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime);
    
    /**
     * 统计用户操作次数
     * @param userId 用户ID
     * @return 操作次数
     */
    @Select("SELECT COUNT(*) FROM data_operation_log WHERE user_id = #{userId}")
    Long countByUserId(@Param("userId") Long userId);
    
    /**
     * 统计指定时间范围内各用户的操作次数
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 用户操作统计
     */
    @Select("SELECT user_id, COUNT(*) as count FROM data_operation_log WHERE operation_time BETWEEN #{startTime} AND #{endTime} GROUP BY user_id")
    List<Map<String, Object>> countByUserId(@Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime);
    
    /**
     * 统计指定操作类型的次数
     * @param operationType 操作类型
     * @return 操作次数
     */
    @Select("SELECT COUNT(*) FROM data_operation_log WHERE operation_type = #{operationType}")
    Long countByOperationType(@Param("operationType") String operationType);
    
    /**
     * 统计指定时间范围内各操作类型的次数
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 操作类型统计
     */
    @Select("SELECT operation_type, COUNT(*) as count FROM data_operation_log WHERE operation_time BETWEEN #{startTime} AND #{endTime} GROUP BY operation_type")
    List<Map<String, Object>> countByOperationType(@Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime);
    
    /**
     * 统计指定表的操作次数
     * @param tableName 表名
     * @return 操作次数
     */
    @Select("SELECT COUNT(*) FROM data_operation_log WHERE table_name = #{tableName}")
    Long countByTableName(@Param("tableName") String tableName);
    
    /**
     * 统计指定时间范围内各表的操作次数
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 表操作统计
     */
    @Select("SELECT table_name, COUNT(*) as count FROM data_operation_log WHERE operation_time BETWEEN #{startTime} AND #{endTime} GROUP BY table_name")
    List<Map<String, Object>> countByTableName(@Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime);
    
    /**
     * 统计操作次数（支持多条件）
     * @param userId 用户ID
     * @param operationType 操作类型
     * @param tableName 表名
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 操作次数
     */
    /*
    @Select("<script>" +
            "SELECT COUNT(*) FROM data_operation_log WHERE 1=1" +
            "<if test='userId != null'> AND user_id = #{userId}</if>" +
            "<if test='operationType != null and operationType != \"\"'> AND operation_type = #{operationType}</if>" +
            "<if test='tableName != null and tableName != \"\"'> AND table_name = #{tableName}</if>" +
            "<if test='startTime != null'> AND operation_time >= #{startTime}</if>" +
            "<if test='endTime != null'> AND operation_time <= #{endTime}</if>" +
            "</script>")
    Long countOperations(@Param("userId") Long userId, @Param("operationType") String operationType, 
                        @Param("tableName") String tableName, @Param("startTime") LocalDateTime startTime, 
                        @Param("endTime") LocalDateTime endTime);
    */
    
    /**
     * 删除指定时间之前的操作日志
     * @param beforeTime 时间点
     * @return 删除的记录数
     */
    @Select("DELETE FROM data_operation_log WHERE operation_time < #{beforeTime}")
    int deleteByOperationTimeBefore(@Param("beforeTime") LocalDateTime beforeTime);
    
    /**
     * 统计指定时间范围内的操作次数
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 操作次数
     */
    @Select("SELECT COUNT(*) FROM data_operation_log WHERE operation_time BETWEEN #{startTime} AND #{endTime}")
    Long countByOperationTimeBetween(@Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime);
    
    /**
     * 统计用户在指定时间范围内的操作次数
     * @param userId 用户ID
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 操作次数
     */
    @Select("SELECT COUNT(*) FROM data_operation_log WHERE user_id = #{userId} AND operation_time BETWEEN #{startTime} AND #{endTime}")
    Long countByUserIdAndOperationTimeBetween(@Param("userId") Long userId, @Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime);
    
    /**
     * 根据描述模糊查询日志
     * @param description 描述关键字
     * @param page 分页参数
     * @return 操作日志分页列表
     */
    @Select("SELECT * FROM data_operation_log WHERE description LIKE CONCAT('%', #{description}, '%') ORDER BY operation_time DESC")
    IPage<DataOperationLog> findByDescriptionLike(@Param("description") String description, Page<DataOperationLog> page);
    
    /**
     * 查询最近的操作日志
     * @param limit 限制数量
     * @return 操作日志列表
     */
    @Select("SELECT * FROM data_operation_log ORDER BY operation_time DESC LIMIT #{limit}")
    List<DataOperationLog> findRecentLogs(@Param("limit") Integer limit);
    
    /**
     * 查询用户最近的操作日志
     * @param userId 用户ID
     * @param limit 限制数量
     * @return 操作日志列表
     */
    @Select("SELECT * FROM data_operation_log WHERE user_id = #{userId} ORDER BY operation_time DESC LIMIT #{limit}")
    List<DataOperationLog> findRecentLogsByUserId(@Param("userId") Long userId, @Param("limit") Integer limit);
    
    /**
     * 查询操作类型统计
     * @return 操作类型统计列表（操作类型，次数）
     */
    @Select("SELECT operation_type, COUNT(*) as count FROM data_operation_log GROUP BY operation_type ORDER BY count DESC")
    List<Object[]> getOperationTypeStatistics();
    
    /**
     * 查询表操作统计
     * @return 表操作统计列表（表名，次数）
     */
    @Select("SELECT table_name, COUNT(*) as count FROM data_operation_log GROUP BY table_name ORDER BY count DESC")
    List<Object[]> getTableOperationStatistics();
    
    /**
     * 查询用户操作统计
     * @return 用户操作统计列表（用户ID，次数）
     */
    @Select("SELECT user_id, COUNT(*) as count FROM data_operation_log WHERE user_id IS NOT NULL GROUP BY user_id ORDER BY count DESC")
    List<Object[]> getUserOperationStatistics();
    
    /**
     * 根据用户ID和表名查询操作日志
     * @param userId 用户ID
     * @param tableName 表名
     * @param page 分页参数
     * @return 操作日志分页列表
     */
    @Select("SELECT * FROM data_operation_log WHERE user_id = #{userId} AND table_name = #{tableName} ORDER BY operation_time DESC")
    IPage<DataOperationLog> findByUserIdAndTableName(@Param("userId") Long userId, @Param("tableName") String tableName, Page<DataOperationLog> page);
    
    /**
     * 根据表名和操作类型查询操作日志
     * @param tableName 表名
     * @param operationType 操作类型
     * @param page 分页参数
     * @return 操作日志分页列表
     */
    @Select("SELECT * FROM data_operation_log WHERE table_name = #{tableName} AND operation_type = #{operationType} ORDER BY operation_time DESC")
    IPage<DataOperationLog> findByTableNameAndOperationType(@Param("tableName") String tableName, @Param("operationType") String operationType, Page<DataOperationLog> page);
    
    /**
     * 获取表操作统计
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 表操作统计列表
     */
    @Select("SELECT table_name, operation_type, COUNT(*) as count FROM data_operation_log WHERE operation_time BETWEEN #{startTime} AND #{endTime} GROUP BY table_name, operation_type ORDER BY count DESC")
    List<Map<String, Object>> getTableOperationStats(@Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime);
    
    /**
     * 获取用户操作统计
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 用户操作统计列表
     */
    @Select("SELECT user_id, operation_type, COUNT(*) as count FROM data_operation_log WHERE operation_time BETWEEN #{startTime} AND #{endTime} GROUP BY user_id, operation_type ORDER BY count DESC")
    List<Map<String, Object>> getUserOperationStats(@Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime);
    
    /**
     * 统计指定时间范围内的操作数量
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 操作数量
     */
    @Select("SELECT COUNT(*) FROM data_operation_log WHERE operation_time BETWEEN #{startTime} AND #{endTime}")
    Long countOperationsByTimeRange(@Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime);
    
    /**
     * 获取操作类型统计
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 操作类型统计列表
     */
    @Select("SELECT operation_type, COUNT(*) as count FROM data_operation_log WHERE operation_time BETWEEN #{startTime} AND #{endTime} GROUP BY operation_type ORDER BY count DESC")
    List<Map<String, Object>> getOperationTypeStats(@Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime);
    
    /**
     * 根据多个条件查询操作日志
     * @param userId 用户ID
     * @param operationType 操作类型
     * @param tableName 表名
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @param page 分页参数
     * @return 操作日志分页列表
     */
    /*
    @Select("<script>" +
            "SELECT * FROM data_operation_log WHERE 1=1" +
            "<if test='userId != null'> AND user_id = #{userId}</if>" +
            "<if test='operationType != null and operationType != \"\"'> AND operation_type = #{operationType}</if>" +
            "<if test='tableName != null and tableName != \"\"'> AND table_name = #{tableName}</if>" +
            "<if test='startTime != null'> AND operation_time >= #{startTime}</if>" +
            "<if test='endTime != null'> AND operation_time <= #{endTime}</if>" +
            " ORDER BY operation_time DESC" +
            "</script>")
    IPage<DataOperationLog> findByConditions(@Param("userId") Long userId, 
                                            @Param("operationType") String operationType,
                                            @Param("tableName") String tableName,
                                            @Param("startTime") LocalDateTime startTime,
                                            @Param("endTime") LocalDateTime endTime,
                                            Page<DataOperationLog> page);
    */
}
